<template>
  <div>
    <div class="card-box">
      <el-card ref="card1" class="elcard" style="flex:1;align-self:normal;">
        <div slot="header" class="hd clearfix">
          <span class="tit">融资信息</span>
        </div>
        <div class="branchBody">
          <el-table
            :data="financing.body"
            v-loading="loading"
            ref="one"
            style="width: 100%; border: none"
            :row-class-name="tableRowClassName"
            :row-style="{ border: 'none' }"
            :cell-style="{ border: 'none' }"
          >
            <el-table-column prop="date" label="融资时间"></el-table-column>
            <el-table-column prop="round" label="融资轮次"></el-table-column>
            <el-table-column
              prop="amount"
              label="融资金额"
              width="180"
            ></el-table-column>
            <el-table-column
              label="投资方"
              prop="investors[0].org_name"
              width="350"
            >
            </el-table-column>
          </el-table>
        </div>
      </el-card>
    </div>
    <!--股权结构-->
    <div class="card-box">
      <el-card ref="card1" class="elcard" style="flex:1;align-self:normal;">
        <div slot="header" class="hd clearfix">
          <span class="tit">股权结构</span>
        </div>
        <div class="tips" :class="[{ show: hasSomeThing }]">
          <p v-for="(item, index) in tips" :key="index">
            <b></b>
            {{ item }}
          </p>
        </div>
        <div id="analysisBox" class="analysisBox">
          <div
            v-show="!hasSomeThing"
            class="structureChart tree-container"
            ref="charts"
            :id="elId"
          ></div>
          <div :class="['nothing', { show: hasSomeThing }]">暂无数据</div>
        </div>
      </el-card>
    </div>
  </div>
</template>
<script>
import $ from "jquery";
export default {
  data() {
    return {
      companyName: this.$route.query.name || "", //公司名称
      structureChart: null,
      structureOption: null,
      hasOther: false,
      tips: ["股东", "对外投资"],
      financing: {
        title: "融资信息",
        body: [],
      },
      loading: false,
      leftHasOther: false,
      rightHasOther: false,
      //树形结构参数
      elId: "",
      leftCount: 0,
      rightCount: 0,
      treeData: {},
      hasSomeThing: false,
      eid: this.$route.query.eid,
    };
  },
  mounted() {
    this.getFinancing(); //获取融资信息
    //树形图
    this.init();
    this.getPatentInfo();
  },
  methods: {
    tableRowClassName({ row, rowIndex }) {
      if (rowIndex % 2) {
        return "warning-row";
      }
      return "";
    },
    /*
     * params: 无
     * return: 无
     * function: 初始化
     * */
    init() {
      let time = new Date().getTime();
      this.elId = "tree_" + time;
    },
    /*
     * params: 无
     * return: 无
     * function: 绘制树
     * */
    drawTree() {
      var ths = this;
      // Calculate total nodes, max label length
      //计算总节点，最大标签长度
      var totalNodes = 0;
      var maxLabelLength = 0;
      // variables for drag/drop
      var selectedNode = null;
      var draggingNode = null;
      // panning variables
      var panSpeed = 200;
      var panBoundary = 20; // Within 20px from edges will pan when dragging.
      // Misc. variables
      var i = 0;
      var duration = 750;
      var root;
      var dragStarted = null;
      var domNode = null;
      var nodes = [];

      // size of the diagram
      var viewerWidth = $("#" + ths.elId).width();
      var viewerHeight = $("#" + ths.elId).height();
      var tree = d3.layout.tree().size([viewerHeight, viewerWidth]);
      // define a d3 diagonal projection for use by the node paths later on.
      //定义一个D3对角线投影，供以后节点路径使用
      var diagonal = d3.svg.diagonal().projection(function (d) {
        return [d.y, d.x];
      });
      // A recursive helper function for performing some setup by walking through all nodes
      //通过遍历所有节点执行一些设置的递归辅助函数
      function visit(parent, visitFn, childrenFn) {
        if (!parent) return;

        visitFn(parent);

        var children = childrenFn(parent);
        if (children) {
          var count = children.length;
          for (var i = 0; i < count; i++) {
            visit(children[i], visitFn, childrenFn);
          }
        }
      }
      // Call visit function to establish maxLabelLength
      //建立最大长度的函数
      visit(
        this.treeData,
        function (d) {
          totalNodes++;
          maxLabelLength = Math.max(d.name.length, maxLabelLength);
        },
        function (d) {
          return d.children && d.children.length > 0 ? d.children : null;
        }
      );
      // sort the tree according to the node names
      //根据节点名称排序树
      function sortTree() {
        tree.sort(function (a, b) {
          return b.name.toLowerCase() < a.name.toLowerCase() ? 1 : -1;
        });
      }
      // Sort the tree initially incase the JSON isn't in a sorted order.
      //如果JSON不按排序顺序，则首先对树进行排序。
      //sortTree();

      // Define the zoom function for the zoomable tree
      //定义可缩放树的缩放函数
      function zoom() {
        svgGroup.attr(
          "transform",
          "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")"
        );
      }

      // define the zoomListener which calls the zoom function on the "zoom" event constrained within the scaleExtents
      //定义zoomListener，它调用在缩放范围内的“缩放”事件上的缩放功能
      var zoomListener = d3.behavior
        .zoom()
        .scaleExtent([0.5, 3])
        .on("zoom", zoom);

      function initiateDrag(d, domNode) {
        draggingNode = d;
        d3.select(domNode)
          .select(".ghostCircle")
          .attr("pointer-events", "none");
        d3.selectAll(".ghostCircle").attr("class", "ghostCircle show");
        d3.select(domNode).attr("class", "node activeDrag");

        svgGroup.selectAll("g.node").sort(function (a, b) {
          // select the parent and sort the path's
          if (a.id != draggingNode.id) return 1;
          // a is not the hovered element, send "a" to the back
          else return -1; // a is the hovered element, bring "a" to the front
        });
        // if nodes has children, remove the links and nodes
        if (nodes.length > 1) {
          // remove link paths
          var links = tree.links(nodes);
          var nodePaths = svgGroup
            .selectAll("path.link")
            .data(links, function (d) {
              return d.target.id;
            })
            .remove();
          // remove child nodes
          var nodesExit = svgGroup
            .selectAll("g.node")
            .data(nodes, function (d) {
              return d.id;
            })
            .filter(function (d, i) {
              if (d.id == draggingNode.id) {
                return false;
              }
              return true;
            })
            .remove();
        }
        // remove parent link
        var parentLink = tree.links(tree.nodes(draggingNode.parent));
        svgGroup
          .selectAll("path.link")
          .filter(function (d, i) {
            //		        	console.log(d)
            if (d.target.id == draggingNode.id) {
              return true;
            }
            return false;
          })
          .remove();

        dragStarted = null;
      }

      // define the baseSvg, attaching a class for styling and the zoomListener
      var baseSvg = d3
        .select("#" + ths.elId)
        .append("svg")
        .attr("width", viewerWidth)
        .attr("height", viewerHeight)
        .attr("class", "overlay")
        .call(zoomListener);
      function endDrag() {
        selectedNode = null;
        d3.selectAll(".ghostCircle").attr("class", "ghostCircle");
        d3.select(domNode).attr("class", "node");
        // now restore the mouseover event or we won't be able to drag a 2nd time
        d3.select(domNode).select(".ghostCircle").attr("pointer-events", "");
        updateTempConnector();
        if (draggingNode !== null) {
          update(root);
          centerNode(draggingNode);
          draggingNode = null;
        }
      }

      // Helper functions for collapsing and expanding nodes.
      function collapse(d) {
        if (d.children) {
          d._children = d.children;
          d._children.forEach(collapse);
          d.children = null;
        }
      }

      function expand(d) {
        if (d._children) {
          d.children = d._children;
          d.children.forEach(expand);
          d._children = null;
        }
      }

      var overCircle = function (d) {
        selectedNode = d;
        updateTempConnector();
      };
      var outCircle = function (d) {
        selectedNode = null;
        updateTempConnector();
      };

      // Function to update the temporary connector indicating dragging affiliation
      var updateTempConnector = function () {
        var data = [];
        if (draggingNode !== null && selectedNode !== null) {
          // have to flip the source coordinates since we did this for the existing connectors on the original tree
          data = [
            {
              source: {
                x: selectedNode.y0,
                y: selectedNode.x0,
              },
              target: {
                x: draggingNode.y0,
                y: draggingNode.x0,
              },
            },
          ];
        }
        var link = svgGroup.selectAll(".templink").data(data);

        link
          .enter()
          .append("path")
          .attr("class", "templink")
          .attr("d", d3.svg.diagonal())
          .attr("pointer-events", "none");

        link.attr("d", d3.svg.diagonal());

        link.exit().remove();
      };

      // Function to center node when clicked/dropped so node doesn't get lost when collapsing/moving with large amount of children.

      function centerNode(source) {
        var scale = zoomListener.scale();
        var x = -source.y0;
        var y = -source.x0;
        x = x * scale + viewerWidth / 2;
        y = y * scale + viewerHeight / 2;

        d3.select("#" + ths.elId)
          .select("g")
          .transition()
          .duration(duration)
          .attr(
            "transform",
            "translate(" + x + "," + y + ")scale(" + scale + ")"
          );
        zoomListener.scale(scale);
        zoomListener.translate([x, y]);
      }

      // Toggle children function

      // function toggleChildren(d) {
      //   if (d.children) {
      //     d._children = d.children;
      //     d.children = null;
      //   } else if (d._children) {
      //     d.children = d._children;
      //     d._children = null;
      //   }
      //   return d;
      // }

      function update(source) {
        // Compute the new height, function counts total children of root node and sets tree height accordingly.
        // This prevents the layout looking squashed when new nodes are made visible or looking sparse when nodes are removed
        // This makes the layout more consistent.
        var levelWidth = [1];
        var childCount = function (level, n) {
          if (n.children && n.children.length > 0) {
            if (levelWidth.length <= level + 1) levelWidth.push(0);

            levelWidth[level + 1] += n.children.length;
            n.children.forEach(function (d) {
              childCount(level + 1, d);
            });
          }
        };
        childCount(0, root);
        var newHeight = d3.max(levelWidth) * 30; // 25 pixels per line每个的上下距离
        tree = tree.size([newHeight, viewerWidth]);

        // Compute the new tree layout.
        var nodes = tree.nodes(root).reverse(),
          links = tree.links(nodes);

        // Set widths between levels based on maxLabelLength.
        //区分左右
        nodes.forEach(function (d) {
          //如果是cite放在右边
          //ref右   cite左
          if (d.type === "cite") {
            //左
            d.y = -d.depth * (maxLabelLength * 6); //maxLabelLength * 10px局中心的距离
            d.x = d.x + 12.5 * ths.rightCount; //两边居中
          } else if (d.type === "ref") {
            //右
            d.y = d.depth * (maxLabelLength * 6); //maxLabelLength * 10px
            d.x = d.x - 12.5 * ths.leftCount; //两边居中
          } else {
            d.y = d.depth * (maxLabelLength * 6); //maxLabelLength * 10px
          }
          // alternatively to keep a fixed scale one can set a fixed depth per level
          // Normalize for fixed-depth by commenting out below line
          // d.y = (d.depth * 500); //500px per level.
        });

        // Update the nodes…
        var node = svgGroup.selectAll("g.node").data(nodes, function (d) {
          return d.id || (d.id = ++i);
        });

        // Enter any new nodes at the parent's previous position.
        var nodeEnter = node
          .enter()
          .append("g")
          .attr("class", "node")
          .attr("transform", function (d) {
            return "translate(" + source.y0 + "," + source.x0 + ")";
          });

        nodeEnter
          .append("circle")
          .attr("class", "nodeCircle")
          .attr("r", 0)
          .style("fill", function (d) {
            return d._children ? "lightsteelblue" : "#fff";
          });

        nodeEnter
          .append("text")
          .attr("x", function (d) {
            //如果是cite放在左边
            if (d.type === "cite") {
              return d.children || d._children ? 10 : -10;
            } else if (d.type === "ref") {
              return d.children || d._children ? -10 : 10;
            } else {
              return d.children || d._children ? 0 : 10;
            }
          })
          .attr("dy", ".35em")
          // .attr('class', 'nodeText')
          .attr("class", function (d) {
            if (d.type === "cite") return "nodeTextLeft";
            else if (d.type === "ref") return "nodeTextRight";
            else return "nodeTextModdle";
          })
          .attr("text-anchor", function (d) {
            //如果是cite放在左边
            if (d.type === "cite") {
              return d.children || d._children ? "start" : "end";
            } else if (d.type === "ref") {
              return d.children || d._children ? "end" : "start";
            } else {
              return d.children || d._children ? "center" : "start";
            }
          })
          .text(function (d) {
            return d.name;
          })
          .style("fill-opacity", 0);

        // phantom node to give us mouseover in a radius around it
        nodeEnter
          .append("circle")
          // .attr('class', 'ghostCircle')
          .attr("class", function (d) {
            if (d.type === "cite") return "circleLeft";
            else if (d.type === "ref") return "circleRight";
          })
          // .attr("r", 30)
          .attr("r", 6) //节点大小
          .attr("opacity", 0.8) // change this to zero to hide the target area
          // .style("fill", "#241C75")//节点颜色
          .attr("pointer-events", "mouseover")
          .on("mouseover", function (node) {
            overCircle(node);
          })
          .on("mouseout", function (node) {
            outCircle(node);
          });

        // Update the text to reflect whether node has children or not.
        node
          .select("text")
          .attr("x", function (d) {
            //如果是cite放在左边
            if (d.type === "cite") {
              return d.children ? 10 : -10;
            } else if (d.type === "ref") {
              return d.children ? -10 : 10;
            } else {
              return d.children ? -30 : 10;
            }
          })
          .attr("y", function (d) {
            //如果是cite放在左边
            if (d.type === "cite" || d.type === "ref") {
              return 0;
            } else {
              return -20;
            }
          })
          .attr("text-anchor", function (d) {
            //如果是cite放在左边
            if (d.type === "cite") {
              return d.children ? "start" : "end";
            } else if (d.type === "ref") {
              return d.children ? "end" : "start";
            } else {
              return d.children ? "center" : "start";
            }
          })
          .text(function (d) {
            return d.name;
          });

        // Change the circle fill depending on whether it has children and is collapsed
        node
          .select("circle.nodeCircle")
          .attr("r", 4.5)
          .style("fill", function (d) {
            return "#fff";
          });

        // Transition nodes to their new position.
        var nodeUpdate = node
          .transition()
          .duration(duration)
          .attr("transform", function (d) {
            return "translate(" + d.y + "," + d.x + ")";
          });

        // Fade the text in
        nodeUpdate.select("text").style("fill-opacity", 1);

        // Transition exiting nodes to the parent's new position.
        var nodeExit = node
          .exit()
          .transition()
          .duration(duration)
          .attr("transform", function (d) {
            return "translate(" + source.y + "," + source.x + ")";
          })
          .remove();

        nodeExit.select("circle").attr("r", 0);

        nodeExit.select("text").style("fill-opacity", 0);
        //树的圆点的点击事件
        function click(d) {
          let index = d.name.indexOf("( 持股");
          if (index > -1) {
            ths.companyName = d.name.substr(0, index);
          } else {
            ths.companyName = d.name;
          }
          if (d.eid && d.eid !== "") {
            ths.eid = d.eid;
            baseSvg.remove();
            ths.getAData();
          } else {
            ths.$message.warning("非工商注册的企业");
          }

          // if(d.qtype==='E'){
          // 	// 重绘
          // 	baseSvg.remove()
          // 	ths.getAData()
          // }else{
          // 	ths.$message.warning('非工商注册的企业')
          // }
        }
        var OCircle = svgGroup.selectAll("circle").on("click", click);

        //文本点击事件
        // svgGroup.selectAll("text")
        //   .on("click", function (d) {
        //     ths.goDetail(d.name);
        //   });

        // Update the links…
        var link = svgGroup.selectAll("path.link").data(links, function (d) {
          return d.target.id;
        });
        // Enter any new links at the parent's previous position.
        link
          .enter()
          .insert("path", "g")
          .attr("class", "link")
          .attr("d", function (d) {
            var o = {
              x: source.x0,
              y: source.y0,
            };
            return diagonal({
              source: o,
              target: o,
            });
          });

        // Transition links to their new position.
        link.transition().duration(duration).attr("d", diagonal);

        // Transition exiting nodes to the parent's new position.
        link
          .exit()
          .transition()
          .duration(duration)
          .attr("d", function (d) {
            var o = {
              x: source.x,
              y: source.y,
            };
            return diagonal({
              source: o,
              target: o,
            });
          })
          .remove();

        // Stash the old positions for transition.
        nodes.forEach(function (d) {
          d.x0 = d.x;
          d.y0 = d.y;
        });
      }

      // Append a group which holds all nodes and which the zoom Listener can act upon.
      var svgGroup = baseSvg.append("g");
      // Define the root
      root = this.treeData;
      root.x0 = viewerHeight / 2;
      root.y0 = 0;

      // Layout the tree initially and center on the root node.
      update(root);
      centerNode(root);
    },
    /*
     * params: 无
     * return: 无
     * function: 获取PN号
     * */
    getPatentInfo() {
      this.getAData();
    },
    /*
     * params: PN号
     * return: 无
     * function: 组装树的数据
     * */
    getAData() {
      let promise = new Promise((resolve, reject) => {
        let res = {
          name: this.companyName,
          children: [],
        };
        let count = 0;
        this.getStock("933c81955e587b0019de2a877e2d67e2", "cite", (data) => {
          if (data.children) {
            this.leftCount = data.children.length || 0;
          }
          if (res.children.length > 0) {
            //保证cite的都在最前面
            res.children = data.children.concat(res.children);
          } else {
            res.children = data.children;
          }
          count++;
          if (count === 2) {
            resolve(res);
          }
        });

        this.getDData("aa0db5d0e91fb921249e31bf2bb9b43a", "ref", (data) => {
          if (data.children) {
            this.rightCount = data.children.length || 0;
          }
          res.children = res.children.concat(data.children);
          count++;
          if (count === 2) {
            resolve(res);
          }
        });
      });
      promise.then((d) => {
        this.treeData = d;
        this.drawTree();
      });
    },
    // 股东
    getStock(tid, type, callback) {
      this.$post(this.$Url.basicInfo.stock, {
        fields: ["eid", "percentage", "name"],
        terms: {
          eid: this.eid,
        },
        eid: this.eid,
        tid,
        ipi: 1,
        ips: 100,
      }).then((data) => {
        if (data.status == 200 && data.data) {
          let datas = data.data;
          let list2 = { children: [] };
          for (let i in datas) {
            let proportion =
              datas[i].sharehdratio !== "" ? datas[i].sharehdratio : 0;
            let listItem = {
              name: datas[i].sharehdName + "( 持股" + proportion + "% )",
              type: type,
              eid: datas[i].sharehdCode,
            };
            list2.children.push(listItem);
          }

          callback && callback(list2);
        }
      });
    },
    //
    getDData(tid, type, callback) {
      this.$post(this.$Url.basicInfo.selectByName, {
        eid: this.eid,
        tid: tid,
        ipi: 1,
        ips: 100,
      })
        .then((data) => {
          if (data.status == 200 && data.data) {
            this.hasSomeThing = false;
            let datas = data.data;
            var list = { children: [] };
            let result = datas.result || [];
            // 子级在右
            if (type == "ref") {
              for (let i in result) {
                let proportion =
                  result[i].stock_percentage !== ""
                    ? result[i].stock_percentage
                    : 0;
                if (parseFloat(proportion) == 1) {
                  proportion = parseFloat(proportion) * 100;
                } else {
                  proportion = (parseFloat(proportion) * 100).toFixed(2);
                }

                if (result[i].invest_name && result[i].invest_name !== "") {
                  let listItem = {
                    name: result[i].invest_name + "( 持股" + proportion + "% )",
                    type: type,
                    eid: result[i].invest_eid,
                    qtype: result[i].type || "",
                  };
                  list.children.push(listItem);
                }
              }
            }
          }

          callback && callback(list);
        })
        .catch((err) => {});
    },
    // 获取融资信息
    getFinancing() {
      this.$post(this.$Url.basicInfo.selectByName, {
        eid: this.eid,
        tid: "b83c4a27ebcb0a7fc99c6b0d2f1ff84f",
        ipi: 1,
        ips: 100,
      })
        .then((data) => {
          let list = data.data && data.data.result;
          for (let i in list) {
            this.$set(list[i], "investors", JSON.parse(list[i].investors));
            if (list[i].amount === 0) {
              this.$set(list[i], "amount", "未披露");
            }
          }
          this.financing.body = list;
        })
        .catch((err) => {});
    },
  },
};
</script>
<style lang="scss" scoped>
.card-box {
  position: relative;
  display: flex;
  align-items: center;
  margin-bottom: 20px;
}
.elcard {
  position: relative;
  flex: .5;
  padding: 0 !important;
  text-align: left !important;
  ::v-deep {
    .el-card__header {
      position: relative;
      &:before {
        position: absolute;
        top: 50%;
        left: 0;
        width: 5px;
        height: 30px;
        margin-top: -15px;
        content: '';
        background-color: $color101;
      }
    }
  }
  .tit {
    font-size: 14px;
    font-weight: bold;
    i {
      color: #504da6;
    }
  }
  .achievements {
    position: relative;
    li {
      display: block;
      border-bottom: 1px solid #EBEEF5;
      margin-bottom: 10px;
    }
  }
}
.el-row {
  background: #fff;
  margin-bottom: 20px;
  .el-table {
    padding: 0 20px;
  }
}
#d3Frame {
  padding-left: 10px;
}
/*g{transform: translate(120, 5);}
	:not(svg) { transform-origin: 0px 0px; }*/

.infoTitle {
  padding-left: 25px;
  margin: 32px 0;
  font-size: 14px;
  color: #241c75;
  font-weight: bold;
  border-left: 5px solid #241c75;
}
/*融资信息*/
.financing,
.structure {
  padding: 1px 0 45px;
  background-color: #fff;
}
.branchBody,
.structureChart {
  width: 100%;
  padding: 0 20px 20px;
}
.branchBody {
  max-height: 300px;
}

/*股权结构*/
.structure {
  margin-top: 30px;
}
.structureChart {
  height: 600px;
}
.structure > .infoTitle {
  margin-bottom: 10px;
}
.analysisBox {
  position: relative;
}
.nothing {
  display: none;
  text-align: center;
  font-size: 15px;
  color: #666;
}
.nothing.show {
  display: block;
  position: relative;
  width: 100%;
  left: 0;
}

.tips,
.tips > p {
  display: flex;
  flex-wrap: nowrap;
}
.tips {
  padding: 0 30px;
  margin-bottom: 20px;
  color: #333;
  font-weight: bold;
}
.tips > p {
  margin-right: 25px;
  align-items: center;
}
.tips > p > b {
  width: 10px;
  height: 10px;
  margin-right: 6px;
  border-radius: 10px;
  background: #2717a1;
}
.tips > p:last-of-type > b {
  background: #b4c4ff;
}
</style>